//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/.
// 			VisualNovelToolkit		     /_/_/_/_/_/_/_/_/_/.
// Copyright ©2013 - Sol-tribe.	/_/_/_/_/_/_/_/_/_/.
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/.
using UnityEngine;
using System.Collections;

/// <summary>
/// ISoundPlayer.
/// </summary>
public class ISoundPlayer : MonoBehaviour{
	public enum Category{
		BGM=0,
		SE,
		VOICE,
	}

	static private ISoundPlayer m_Instance;
	public static ISoundPlayer Instance {
		get {	
			return m_Instance;
		}
	}			

	static public float kMusicFadeTimeOnClickBack = 1f;	// sec.
	static public float kPlayDelayWhenLoaded = 1f;
	static public float kOnLoadPlayBGMWaitSec = 2f;
	
	public bool m_PlayMusicAtStart; 	// check this from inspector.
	public string m_StartMusicName;
	public float m_StartMusicDelay = 0f;
	
	protected int k_BgmPoolNum = 2;
	protected int k_SeAndVoicePlayMax = 4;

	protected GameObject[] m_AudioPool;	// Voice and Se0 and Se1 and Se2.
	protected int m_VoiceIndex = 0;
	
	void Awake(){
		if( ! Application.isPlaying ){
			return;
		}

		if( Instance == null ){
			m_Instance = this;
//			gameObject.hideFlags = HideFlags.NotEditable;
			
			if( k_SeAndVoicePlayMax == 0 ){
				Debug.LogWarning( "SE and Voice can't play because the k_SeAndVoicePlayMax is ZERO !" );
			}
			else{
				Transform self = transform;
				m_AudioPool = new GameObject[ k_SeAndVoicePlayMax ];
				for( int i=0;i<k_SeAndVoicePlayMax;i++){
					m_AudioPool[ i ]  = new GameObject( "_AudioPool_" + i.ToString() );
					m_AudioPool[ i ].AddComponent<AudioSource>();
					m_AudioPool[ i ].transform.parent = self;
				}
			}			
			OnAwake();			
		}
		else{
			if( Application.isPlaying ){
				Destroy( gameObject );		
			}
		}				
	}		

	void Start(){
		OnStart();
	}	

	void OnEnable(){
//		Debug.Log( "OnEnable:" + name );
		m_Instance = this;
	}

	void OnDisable(){
//		Debug.Log( "OnDisable:" + name );
		m_Instance = null;
	}	

	void OnDestroy(){
//		Debug.Log( "OnDestroy:" + name );
		m_Instance = null;
	}	
		
	virtual public void OnAwake(){}
	
	virtual public void OnSave( ViNoSaveInfo info ){}

	virtual public void OnLoad( ViNoSaveInfo info ){}

	virtual public void OnStart(){}
	
	virtual public void BGMVolumeChanged( float val  ){}

	virtual public void SEVolumeChanged( float val  ){}

	virtual public void VoiceVolumeChanged( float val  ){	}
	
	virtual public void PlayAudioClip( AudioClip clip , string resourcePath , float volume , float delay ){}

	virtual public void PlayMusic( Hashtable param ){}

	virtual public void PlayMusic( string path , bool loop , float xchbgmTime = 0f ){}

	virtual public void PlayMusic( string name , float volume , float delay ){}

	virtual public void PlayMusic( int id , float volume , float delay ){}	
	
	virtual public void PlaySE( string name , float volume , float delay ){}

	virtual public void PlaySE( string path , bool loop , float xchbgmTime = 0f ){}
		
	virtual public void PlaySE( int id , float volume , float delay ){}	
	
	virtual public void PlayVoice( string name , float volume , float delay ){}
	
	virtual public void PlayVoice( int id , float volume , float delay ){}	
	
	virtual public void PlayVoice( string path , bool loop , float xchbgmTime = 0f ){}
	
	virtual public void StopMusic( float fadeTime ){}
	
	virtual public void StopSE(){}
	
	virtual public void StopSE( string name ,  float fadeTime ){}	

	virtual public void StopVoice(){}
	
	virtual public void StopVoice( string name ,  float fadeTime ){}	
		
	// This is Callback from VM.
	// category is Music or SE or Voice.
	public void PlaySoundCallback( string name , string category , float catVol , float delay ){			
		ViNoDebugger.Log ( "Sound" , "PlaySound Callback." );
				
		if( category.Equals( "Music" ) ){
			float realVol = ViNoConfig.prefsBgmVolume * catVol;			
			PlayMusic( name , realVol , delay );				
		}
		else if( category.Equals( "SE" ) ){
			float realVol = ViNoConfig.prefsSeVolume * catVol;			
			PlaySE( name , realVol , delay );				
		}
		else if( category.Equals( "Voice" ) ){
			float realVol = ViNoConfig.prefsVoiceVolume * catVol;			
			PlayVoice( name , realVol , delay );				
		}								
	}
	
	// This is Callback from VM.
	// category is Music or SE or Voice.
	public void StopSoundCallback( string name , string category , float fadetime ){				
		if( category.Equals( "Music" ) ){				
			StopMusic( fadetime );
		}
		else if( category.Equals( "SE" ) ){
			StopSE ( name , fadetime );
		}
		else if( category.Equals( "Voice" ) ){
			StopVoice( name , fadetime );
		}								
	}
	
	/// <param name='index'>
	/// Index start from 1 to 3. 
	/// </param>
	public bool IsPlayingSE( int index ){
		if( index >= k_SeAndVoicePlayMax ){
			return false;
		}
		else{
			return m_AudioPool[ index ].audio.isPlaying;
		}
	}
	
	/// <summary>
	/// Determines whether this instance is playing voice.
	/// </summary>
	/// <returns>
	/// <c>true</c> if this instance is playing voice; otherwise, <c>false</c>.
	/// </returns>
	public bool IsPlayingVoice(){
		return IsPlaying( m_AudioPool[ m_VoiceIndex ].audio );
	}
	
	protected bool IsPlaying( AudioSource audioSource ){
		if( audioSource != null ){
			return audioSource.isPlaying;
		}
		else{
			return false;
		}		
	}

/*	/// <summary>
	/// Get BGM GO Attached a AudioSource.
	/// </summary>
	public GameObject GetGOBGMPool(){
		for( int i=0;i<k_BgmPoolNum;i++){
			if( ! m_BGMAudioPool[ i ].activeInHierarchy ){
				m_BGMAudioPool[ i ].gameObject.SetActive( true );
				return m_BGMAudioPool[ i ].gameObject;
			}
		}
		return null; // Busy.
	}
//*/
	
	/// <summary>
	/// Delaies the play background.
	/// </summary>
	/// <returns>
	/// The play background.
	/// </returns>
	/// <param name='bgm'>
	/// Bgm.
	/// </param>
	IEnumerator DelayPlayBGM( string bgm ){		
		yield return new WaitForSeconds( kOnLoadPlayBGMWaitSec );
		
		PlayMusic( bgm   , ViNoConfig.prefsBgmVolume , kPlayDelayWhenLoaded );		
	}

	
}